﻿using System;
using System.ComponentModel.Composition;
using System.Diagnostics;
using EnvDTE;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Utilities;

namespace KineticScroll
{
	/// <summary>
	/// Creates the KineticScrollMouseProcessor for a text view.
	/// </summary>
	[Export(typeof(IMouseProcessorProvider))]
	[ContentType("code")]
	[TextViewRole(PredefinedTextViewRoles.Editable)]
	[Name("Kinetic Scroll Mouse Processor")]
	internal sealed class KineticScrollMouseProcessorProvider : IMouseProcessorProvider
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="KineticScrollMouseProcessorProvider"/> class.
		/// </summary>
		/// <param name="serviceProvider">The Visual Studio DTE service provider to import.</param>
		[ImportingConstructor()]
		private KineticScrollMouseProcessorProvider(
			[Import(typeof(SVsServiceProvider))]
			IServiceProvider serviceProvider)
		{
			try
			{
				// Load settings from the Visual Studio DTE
				DTE dte = (DTE)serviceProvider.GetService(typeof(DTE));
				EnvDTE.Properties properties = dte.get_Properties(PackageConstants.OptionsPageCategoryResourceID, PackageConstants.OptionsPageNameResourceID);

				Settings.Instance.MiddleClickEnabled = (bool)properties.Item("MiddleClickEnabled").Value;
				Settings.Instance.MouseWheelEnabled = (bool)properties.Item("MouseWheelEnabled").Value;
				Settings.Instance.RefreshInterval = (double)properties.Item("RefreshInterval").Value;
				Settings.Instance.Deceleration = (double)properties.Item("Deceleration").Value;
				Settings.Instance.MaxVelocity = (double)properties.Item("MaxVelocity").Value;
				Settings.Instance.MouseWheelAccelerationFactor = (double)properties.Item("MouseWheelAccelerationFactor").Value;

				// Poor man's upgrade routine
				Settings.Instance.InstalledVersion = (string)properties.Item("InstalledVersion").Value;
				UpgradeVersion10To11(properties);
			}
			catch (Exception ex)
			{
				Trace.WriteLine("KineticScrollMouseProcessorProvider:  " + ex.Message);
			}
		}

		private void UpgradeVersion10To11(EnvDTE.Properties properties)
		{
			if (string.IsNullOrEmpty(Settings.Instance.InstalledVersion))
			{
				// Update the deceleration value to the new default, otherwise everyone's going to be sliding all over the place
				Settings.Instance.Deceleration = Settings.DecelerationDefaultValue;
				properties.Item("Deceleration").Value = Settings.DecelerationDefaultValue;

				// Now we're on 1.1
				Settings.Instance.InstalledVersion = "1.1";
				properties.Item("InstalledVersion").Value = "1.1";
			}
		}

		/// <summary>
		/// Creates an <see cref="T:Microsoft.VisualStudio.Text.Editor.IMouseProcessor"/> for a <see cref="T:Microsoft.VisualStudio.Text.Editor.IWpfTextView"/>.
		/// </summary>
		/// <param name="wpfTextView">The <see cref="T:Microsoft.VisualStudio.Text.Editor.IWpfTextView"/> for which to create the <see cref="T:Microsoft.VisualStudio.Text.Editor.IMouseProcessor"/>.</param>
		/// <returns>
		/// The created <see cref="T:Microsoft.VisualStudio.Text.Editor.IMouseProcessor"/>.
		/// The value may be null if this <see cref="T:Microsoft.VisualStudio.Text.Editor.IMouseProcessorProvider"/> does not wish to participate in the current context.
		/// </returns>
		public IMouseProcessor GetAssociatedProcessor(IWpfTextView wpfTextView)
		{
			return wpfTextView.Properties.GetOrCreateSingletonProperty<KineticScrollMouseProcessor>(delegate { return new KineticScrollMouseProcessor(wpfTextView); });
		}
	}
}
